/*
 * @Date         : 2022-06-15 14:27:18
 * @LastEditTime: 2025-01-17 11:21:14
 * @LastEditors: Liu 2689810937@qq.com
 * @Description  :  显示屏通讯头文件，包含迪文屏串口协议
 * @FilePath     : \template\btn_scan\Protocol.h
 * @FileLog      :
 */
#ifndef PROTOCOL_H
#define PROTOCOL_H

#include "pro_config.h"
#include "uart2.h"
#include "string.h"
#include "btn_scan.h"

//类型重定义
/* ####################################结构体声明################################# */
/* 读写寄存器结构体 */
typedef struct
{
    u16 functionMode;             /* 功能模式 */
    u16 endoscopeMode;            /* 内镜模式 */
    u16 knobWhiteLightLevel;      /* 旋钮白光等级 */
    u16 knob405;                  /* 旋钮405 */
    u16 knob488;                  /* 旋钮488 */
    u16 knob525;                  /* 旋钮525 */
    u16 fluorescenceOverallLevel; /* 荧光整体等级 */
    u16 knobMode;                 /* 旋钮模式 */
    u16 connectionStatus;         /* 连接状态 */
    u16 initializationSteps;      /* 初始化步骤 */

    u16 reserver1[100]; /* 预留空间 */
} rwStruct;
/* 只读结构体 */
typedef struct
{
    u16 reserver;
} rStruct;
/* 只写寄存器结构体 */
typedef struct
{
    u16 reserver;

} wStruct;

typedef struct
{
    wStruct regW;      /* 只写寄存器组 */
    rwStruct regRW;    /* 读写寄存器组 */
    u16 crc16;         /* crc16，用于保存参数时校验 */
    rStruct regR;      /* 只读寄存器组 */
    u16 regRSIZE;      /* 只读寄存器组大小 */
    u16 regWSIZE;      /* 只写寄存器组大小 */
    u16 regRWSIZE;     /* 读写寄存器组大小 */
    u16 flashSaveSize; /* 要保存的数据大小 */
} regStruct;
extern regStruct regSt;

/* 协议结构体 */
typedef struct
{
    u8 head[3]; /* 帧头 */
    struct addr
    {
        u8 srcAddr : 4; /* 源地址 */
        u8 desAddr : 4; /* 目标地址 */
    } addrSt;
    struct cmd
    {
        u8 cmdCode : 4;    /* 功能码 0x3：读寄存器 0x6：写寄存器 */
        u8 cmdErrCode : 3; /* 命令应答码 0-命令帧正确；1- 校验错误；2-数据长度有误；
                             3- 用户寄存器地址无效；4-目标设备目前状态无法响应命令；5-7：其他错误 */
        u8 cmdAck : 1;     /* 命令方向 0：下发 1：应答 */
    } cmdSt;
    u8 dataAreaNum;
    u16 dataAreaLen;
    u8 dataArea[DATA_AREA_SIZE];
    u16 crc16;
} protocolStruct;
extern protocolStruct protocolSt;

typedef struct
{
    u16 regAddr[10];
    u8 regNum[10];
} addrAndNumStruct;
extern addrAndNumStruct addrAndNumSt;
/* ####################################宏定义################################# */
#define PROTOCOL_READ 0x03
#define PROTOCOL_WRITE 0x06

#define ERR_NONE 0     /* 无错误 */
#define ERR_CRC 1      /* 校验错误 */
#define ERR_LEN 2      /* 数据长度错误 */
#define ERR_REG 3      /* 用户寄存器地址无效 */
#define ERR_BUSY 4     /* 设备繁忙 */
#define ERR_CODE 5     /* 功能码错误 */
#define ERR_ADDR_CMD 6 /* 命令或者地址错误 */

#define LCD_ADDR 0     /* 屏幕地址 */
#define MAIN_ADDR 1    /* 主板地址 */
#define RFID_ADDR 2    /* RFID地址 */
#define POWER_ADDR 3   /* 功率回采板地址 */
#define DRIVER1_ADDR 4 /* 驱动板1地址 */
#define DRIVER2_ADDR 5 /* 驱动板2地址 */
#define GPRS_ADDR 6    /* GPRS地址 */
#define PC_ADDR 7      /* PC上位机*/
/* ####################################函数声明################################# */
#define RESERVER_PTR 0x0000, 0x0
#define PTR_NUM_1 RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, \
                  RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, 1
#define PTR_NUM_2 RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, \
                  RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, 2
#define PTR_NUM_3 RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, \
                  RESERVER_PTR, RESERVER_PTR, 3
#define PTR_NUM_4 RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, \
                  RESERVER_PTR, 4
#define PTR_NUM_5 RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, 5
#define PTR_NUM_6 RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, 6
#define PTR_NUM_7 RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, 7
#define PTR_NUM_8 RESERVER_PTR, RESERVER_PTR, 8
#define PTR_NUM_9 RESERVER_PTR, 9
#define PTR_NUM_10 10
u8 crc_check(u8 *in_buf, u16 in_buf_len);
u16 crc16(u8 *Pushdata, u16 length);
u8 protocol_recv_deal(void);
void serial_recv_response(u8 errCode);
void protocol_init(void);
void user_system_init(void);
u8 protocol_writeCmdDataArea_deal(void);
u8 protocol_readCmdDataArea_deal(void);
u16 read_reg_value(u16 regAddr);
u8 protocol_readOnlyCmdDataArea_deal(void);
void protocol_send_reg(u8 mcode,
                       u16 regAddr0, u8 regNum0,
                       u16 regAddr1, u8 regNum1,
                       u16 regAddr2, u8 regNum2,
                       u16 regAddr3, u8 regNum3,
                       u16 regAddr4, u8 regNum4,
                       u16 regAddr5, u8 regNum5,
                       u16 regAddr6, u8 regNum6,
                       u16 regAddr7, u8 regNum7,
                       u16 regAddr8, u8 regNum8,
                       u16 regAddr9, u8 regNum9,
                       u8 ptrNum);
void protocol_send_RFID(u8 mcode,
                        u16 regAddr0, u8 regNum0,
                        u16 regAddr1, u8 regNum1,
                        u16 regAddr2, u8 regNum2,
                        u16 regAddr3, u8 regNum3,
                        u16 regAddr4, u8 regNum4,
                        u16 regAddr5, u8 regNum5,
                        u16 regAddr6, u8 regNum6,
                        u16 regAddr7, u8 regNum7,
                        u16 regAddr8, u8 regNum8,
                        u16 regAddr9, u8 regNum9,
                        u8 ptrNum);
void protocol_thread(void);

#endif
